from dataclasses import dataclass
from hashlib import sha256

from fastapi.exceptions import HTTPException
from starlette import status

from app.controllers.base_controller import BaseController
from app.models.account_models import Account
from app.schemas.auth_schemas import (LoginRequestSchema, LoginResponseSchema,
                                      RegistrationRequestSchema,
                                      RegistrationResponseSchema)
from app.tools.account_tools import AccountTools


@dataclass
class RegistrationController(BaseController):
    """Контроллер регистрации"""

    request: RegistrationRequestSchema

    async def execute(self) -> RegistrationResponseSchema:
        AccountTools.validate_account_request(request=self.request)
        await AccountTools.check_email_conflict(email=self.request.email)

        new_user = await Account.create(
            firstName=self.request.firstName,
            lastName=self.request.lastName,
            email=self.request.email,
            password=sha256(self.request.password.encode("utf-8")).hexdigest(),
        )

        return RegistrationResponseSchema(
            id=new_user.id,
            firstName=new_user.firstName,
            lastName=new_user.lastName,
            email=new_user.email,
        )


@dataclass
class LoginController(BaseController):
    """Контроллер логина"""

    request: LoginRequestSchema

    async def execute(self) -> LoginResponseSchema:
        user = await Account.get_or_none(
            email=self.request.email,
            password=sha256(self.request.password.encode("utf-8")).hexdigest(),
        )

        if user is None:
            raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED)

        return LoginResponseSchema(id=user.id)
